package com.ambitor.ipro.app.sche;

import java.sql.SQLException;
import java.util.Date;

import com.ambitor.grass.sql.dao.SuperDao;
import com.ambitor.grass.util.data.DataMap;
import com.ambitor.grass.util.data.DatasetList;
import com.ambitor.grass.util.data.IData;
import com.ambitor.grass.util.data.IDataset;
import com.ambitor.ipro.entities.TradeState;
import com.ambitor.ipro.exceptions.ProException;
import com.ambitor.ipro.service.BaseService;
import com.ambitor.ipro.service.TopService;
import com.ambitor.ipro.util.Constants;
import com.ambitor.ipro.util.ResultCode;
import com.ambitor.ipro.util.SkyenccUtil;
import com.ambitor.ipro.util.TableName;

public class BaseExecutor extends BaseService {

	protected TopService topService = null;

	protected IData task = null;

	protected boolean retryFlag = false;

	public BaseExecutor(SuperDao superDao, TopService topService) {
		super(superDao);
		this.topService = topService;
	}

	public void setTask(IData task) {
		this.task = task;
	}

	public void setTryFlag(boolean retryFlag) {
		this.retryFlag = retryFlag;
	}

	@SuppressWarnings("unchecked")
	protected void logTaskStart() {
		IData updateTask = new DataMap();
		String batchId = task.getString("BATCH_ID");
		updateTask.put("BATCH_ID", batchId);
		updateTask.put("TRADE_STATE", TradeState.BEING_EXECUTE);// 开始执行
		updateTask.put("EXEC_TIME", SkyenccUtil.formatDate(new Date()));// 开始执行时间
		try {
			superDao.update("TF_P_TRADE_PRO_BATCH", updateTask);
		} catch (Exception e) {
			logger.error("更新BATCH_ID=" + batchId + "的工单的开始执行时间出现错误", e);
		}
	}

	@SuppressWarnings("unchecked")
	protected void logTaskQuit(ProException e) {
		String batchId = task.getString("BATCH_ID");
		logger.warn("预执行BATCH_ID=" + batchId + "的工单时出现错误，退出预执行。");
		logger.warn(e.toString(), e);
		IData tradeProBatchLog = new DataMap();
		tradeProBatchLog.put("BATCH_ID", batchId);
		tradeProBatchLog.put("LOG_TIME", SkyenccUtil.formatDate(new Date()));
		tradeProBatchLog.put("EXP_TYPE", e.getType());
		tradeProBatchLog.put("EXP_DESC", e.getDesc());
		tradeProBatchLog.put("EXP_CODE", e.getCode());
		tradeProBatchLog.put("EXP_MSG", e.getMsg());
		tradeProBatchLog.put("EXP_SUB_CODE", e.getSubCode());
		tradeProBatchLog.put("EXP_SUB_MSG", e.getSubMsg());
		try {
			superDao.delete("TL_P_TRADE_PRO_BATCH", tradeProBatchLog);
			superDao.insert("TL_P_TRADE_PRO_BATCH", tradeProBatchLog);
		} catch (Exception exp) {
			logger.warn("保存TL_P_TRADE_PRO_BATCH出现数据库异常", exp);
		}

		IData updateTask = new DataMap();
		updateTask.put("BATCH_ID", batchId);
		updateTask.put("TRADE_STATE", TradeState.QUIT_EXECUTE);// 执行终止
		try {
			superDao.update("TF_P_TRADE_PRO_BATCH", updateTask);
		} catch (Exception exp) {
			logger.error("更新BATCH_ID=" + batchId + "的工单到中止状态出现异常", exp);
		}
	}

	@SuppressWarnings("unchecked")
	protected void logTaskEnd(int[] result) {
		IData updateTask = new DataMap();
		updateTask.put("BATCH_ID", task.getString("BATCH_ID"));
		if (retryFlag) {
			int oldSumNum = task.getInt("IID_SUM_NUM", -1);
			if (oldSumNum == -1) {
				updateTask.put("IID_SUM_NUM", result[0]);
				updateTask.put("IID_ERROR_NUM", result[1]);
			} else {
				int oldErrorNum = task.getInt("IID_ERROR_NUM");
				int newErrorNum = oldErrorNum - (result[0] - result[1]);
				updateTask.put("IID_ERROR_NUM", newErrorNum);
			}
		} else {
			updateTask.put("IID_SUM_NUM", result[0]);
			updateTask.put("IID_ERROR_NUM", result[1]);
		}
		if (updateTask.getInt("IID_ERROR_NUM", -1) == 0) {
			updateTask.put("TRADE_STATE", TradeState.EXECUTED_SUCCESS);// 执行成功结束
			updateTask.put("FINISH_TIME", SkyenccUtil.formatDate(new Date()));// 执行成功时间
		} else {
			updateTask.put("TRADE_STATE", TradeState.EXECUTED_EXIST_FAIL);// 执行结束部分成功
		}
		try {
			superDao.update("TF_P_TRADE_PRO_BATCH", updateTask);
		} catch (Exception e) {
			logger.error("更新BATCH_ID=" + task.getString("BATCH_ID")
					+ "的工单的完工情况出现错误", e);
		}

		if (updateTask.getInt("IID_ERROR_NUM", -1) == 0) {
			moveTradeProBatchToHistory();
		}
	}

	@SuppressWarnings("unchecked")
	private void moveTradeProBatchToHistory() {
		IData updateTask = new DataMap();
		String batchId = task.getString("BATCH_ID");
		updateTask.put("BATCH_ID", batchId);
		try {
			IData tradeProBatch = superDao.queryByPK("TF_P_TRADE_PRO_BATCH",
					updateTask);
			superDao.getBaseDao().getConnection().setAutoCommit(false);
			superDao.delete("TF_PH_TRADE_PRO_BATCH", tradeProBatch);
			superDao.insert("TF_PH_TRADE_PRO_BATCH", tradeProBatch);
			superDao.delete("TF_P_TRADE_PRO_BATCH", tradeProBatch);
			try {
				superDao.getBaseDao().getConnection().commit();
			} catch (SQLException e1) {
			}
		} catch (Exception e) {
			logger.error("把BATCH_ID=" + batchId + "的工单移动到历史表出现错误", e);
			try {
				superDao.getBaseDao().getConnection().rollback();
			} catch (SQLException e1) {
			}
		} finally {
			try {
				superDao.getBaseDao().getConnection().setAutoCommit(true);
			} catch (SQLException e) {
			}
		}
	}

	@SuppressWarnings("unchecked")
	protected void deleteItemPros(IDataset tradePros) throws Exception {
		String place = task.getString("PLACE");
		IDataset deleteItemPros = new DatasetList();
		if ("ALL".equalsIgnoreCase(place)) {
			for (int i = 0; i < tradePros.size(); i++) {
				IData tradePro = tradePros.getData(i);
				IData deleteItemPro = new DataMap();
				deleteItemPro.put("INSTALL_IID", tradePro.getString("IID"));
				deleteItemPros.add(deleteItemPro);
			}
			String sql = "delete from TF_P_ITEM_PRO where install_iid = :INSTALL_IID";

			try {
				superDao.getBaseDao().executeBatch(sql, deleteItemPros);
			} catch (Exception exp) {
				logger.warn("删除TF_P_ITEM_PRO数据库异常", exp);
			}
		} else {
			for (int i = 0; i < tradePros.size(); i++) {
				IData tradePro = new DataMap();
				IData deleteItemPro = new DataMap();
				deleteItemPro.put("INSTALL_IID", tradePro.getString("IID"));
				deleteItemPro.put("INSTALL_PLACE", tradePro.getString("PLACE"));
				deleteItemPros.add(deleteItemPro);
			}
			try {
				superDao.delete("TF_P_ITEM_PRO", deleteItemPros);
			} catch (Exception exp) {
				logger.warn("删除TF_P_ITEM_PRO数据库异常", exp);
			}
		}
	}

	@SuppressWarnings("unchecked")
	protected void updateItemPros(IDataset tradePros) throws Exception {
		IDataset itemPros = new DatasetList();
		for (int i = 0; i < tradePros.size(); i++) {
			IData tradePro = tradePros.getData(i);
			IData itemPro = new DataMap();
			itemPro.put("INSTALL_IID", tradePro.getString("IID"));
			itemPro.put("INSTALL_PLACE", tradePro.getString("PLACE"));
			itemPro.put("USER_ID", task.getString("USER_ID"));
			itemPro.put("PRO_ID", task.getString("PRO_ID"));
			itemPros.add(itemPro);
		}
		try {
			superDao.delete("TF_P_ITEM_PRO", itemPros);
			superDao.insert("TF_P_ITEM_PRO", itemPros);
		} catch (Exception exp) {
			logger.warn("保存TF_P_ITEM_PRO出现数据库异常", exp);
		}
	}

	// 新增安装日志表
	@SuppressWarnings("unchecked")
	protected void insertTradePros(IDataset tradePros) throws Exception {
		IDataset params = new DatasetList();
		for (int i = 0; i < tradePros.size(); i++) {
			IData tradePro = tradePros.getData(i);
			IData param = new DataMap();
			param.put("BATCH_ID", task.getString("BATCH_ID"));
			param.put("IID", tradePro.getString("IID"));
			params.add(param);
		}
		String sql = "delete from TL_P_TRADE_PRO where batch_id = :BATCH_ID "
				+ "  and iid = :IID";
		superDao.getBaseDao().executeBatch(sql, params);
		superDao.insert("TL_P_TRADE_PRO", tradePros);
	}

	@SuppressWarnings("unchecked")
	protected IData getUserSession() throws ProException {
		IData userSession = null;
		try {
			userSession = superDao.queryByPK(TableName.TF_P_USER_SESSION, task);
		} catch (Exception e) {
			throw new ProException(ResultCode.DB_EXCEPTION,
					"获取TF_P_USER_SESSION时发生异常", e);
		}
		if (userSession.size() == 0)
			throw new ProException(ResultCode.BUSSINESS_EXCEPTION,
					"userSession表中没有该用户信息");
		if (Constants.FLAG_NO.equals(userSession.getString("VALID_FLAG"))) {
			throw new ProException(ResultCode.BUSSINESS_EXCEPTION,
					"userSession表中该用户SessionId失效");
		}
		return userSession;
	}
}
